<?php 
namespace app\wechatmp\controller;
use think\facade\View;
use think\facade\Cache;
use think\facade\Cookie;
use think\facade\Session;
use app\common\model\UserWx as UserWxModel;
use app\common\model\WechatKeywords as WechatKeywordsModel;
use app\common\model\Jobs as JobsModel;
use app\common\model\Company as CompanyModel;
use app\common\model\Article as ArticleModel;
use app\bsadmin\model\Admin as AdminModel;
use helper\Wechat as WechatHelper;
use think\exception\HttpResponseException;
class Wechat extends Base
{
    public $fromUsername='';
    public $toUsername='';
    public $time=0;
    /**
     * [__construct 构造函数]
     * @return [type] [description]
     */
    public function __construct(){
        parent::__construct();
    }
    public function wechat()
    {
        //获得参数 signature nonce token timestamp echostr
        // p(Cache::get('wxTokenGet'));
        $G=request()->get();
        if(!empty($G['echostr'])){
            Cache::set('wxTokenGet',$G);
            $signature = $G['signature'];
            //形成数组，然后按字典序排序
            $singArr = [
                'nonce'     =>  $G['nonce'],
                'timestamp' =>  $G['timestamp'],
                'token'     =>  config('xy_wechat_mp.token'),
            ];
            sort($singArr);
            //拼接成字符串,sha1加密 ，然后与signature进行校验
            $str = sha1( implode( $singArr ) );
            if( $str == $signature && $G['echostr'] ){
                //第一次接入weixin api接口的时候
                exit($G['echostr']);
            }
        }
        $postStr = file_get_contents("php://input");
        //extract post data
        if (empty($postStr))
        {
            exit("异常请求，请使用微信验证请求");
        }
        libxml_disable_entity_loader(true);
        $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
        try {
            $this->handleRun($postObj);
        } catch (\think\Exception $e) {
            $this->textreply($e->getMessage());
        }
    }
    public function handleRun($postObj)
    {
        $this->fromUsername = $postObj->FromUserName;
        $this->toUsername = $postObj->ToUserName;
        $this->time=time();
        $keyword = trim($postObj->Content);
        //用户位置
        if ($postObj->MsgType == 'event' && $postObj->Event == 'LOCATION')
        {
            exit();
        }
        /*
         * 1、click：点击推事件
         * 用户点击click类型按钮后，微信服务器会通过消息接口推送消息类型为event的结构给开发者（参考消息接口指南）
         * 并且带上按钮中开发者填写的key值，开发者可以通过自定义的key值与用户进行交互；
         */
        if($postObj->MsgType == 'event' && $postObj->Event == 'CLICK')
        {
            $keyword = trim($postObj->EventKey);
        }

        //用户已关注
        if ($postObj->MsgType == 'event' && $postObj->Event == 'SCAN')
        {
            $this->handleEventKey($postObj->EventKey);
        }
        //取消关注事件
        if ($postObj->MsgType == 'event' && $postObj->Event == 'unsubscribe')
        {
            $UserWxModel=UserWxModel::where(['wx_openid'=> $this->fromUsername])->find();
            if ($UserWxModel) {
                $UserWxModel->subscribe=0;
                $UserWxModel->save();
            }
        }


        //关注事件
        if ($postObj->MsgType == 'event' && $postObj->Event == 'subscribe')
        {
            $UserWxModel=UserWxModel::where(['wx_openid'=> $this->fromUsername])->find();
            if ($UserWxModel) {
                $UserWxModel->subscribe=1;
                $UserWxModel->save();
                $keyword='subscribe';
            }
            if ($postObj->EventKey)
                $this->handleEventKey($postObj->EventKey);
        }
        // 文本回复
        $WechatKeywordsModel = WechatKeywordsModel::where(['keyword'=> $keyword])->find();
        if($WechatKeywordsModel)
        {
            switch ($WechatKeywordsModel->type) {
                case 'event':
                    switch ($WechatKeywordsModel->value) {
                        case 'getSelfOpenId':
                            $this->getSelfOpenId();
                            break;
                        case 'getJobsInfo':
                            $this->getJobsInfo(0);
                            break;
                        case 'Bind':
                            $this->Bind();
                            break;
                        case 'unBind':
                            $this->unBind();
                            break;
                    }
                    break;
                case 'image':
                    $this->imagereply($WechatKeywordsModel->value);
                    break;
                case 'video':
                    $this->videoreply($WechatKeywordsModel->value,$keyword);
                    break;
                case 'video':
                    break;
                default:
                    $this->textreply($WechatKeywordsModel->value);
                    break;
            }
        }elseif($keyword==='subscribe'&&$UserWxModel){
            $content = base64_decode($UserWxModel->nickname)."，欢迎回来！" ;
            $this->textreply($content);
        }
        // 文本回复
        $WechatKeywordsDefault = WechatKeywordsModel::where(['is_default'=>1])->find();
        $contentStr = $WechatKeywordsDefault ? $WechatKeywordsDefault->value : "我还没有懂您的意思\n请换一个词好吗？ ^_^";
        $this->textreply($contentStr);
    }
    private function textreply($text)
    {
        $textTpl = "<xml>
        <ToUserName><![CDATA[%s]]></ToUserName>
        <FromUserName><![CDATA[%s]]></FromUserName>
        <CreateTime>%s</CreateTime>
        <MsgType><![CDATA[%s]]></MsgType>
        <Content><![CDATA[%s]]></Content>
        <FuncFlag>0</FuncFlag>
        </xml>";
        $resultStr = sprintf($textTpl, $this->fromUsername, $this->toUsername, $this->time, 'text', $text);
        throw new HttpResponseException(xml($resultStr));
    }
    private function imagereply($image)
    {
        $textTpl = "<xml>
          <ToUserName><![CDATA[%s]]></ToUserName>
          <FromUserName><![CDATA[%s]]></FromUserName>
          <CreateTime>%s</CreateTime>
          <MsgType><![CDATA[%s]]></MsgType>
          <Image>
            <MediaId><![CDATA[%s]]></MediaId>
          </Image>
        </xml>";
        $resultStr = sprintf($textTpl, $this->fromUsername, $this->toUsername, $this->time, 'image', $image);
        throw new HttpResponseException(xml($resultStr));
    }
    private function videoreply($video,$keyword)
    {
        $textTpl = "<xml>
          <ToUserName><![CDATA[%s]]></ToUserName>
          <FromUserName><![CDATA[%s]]></FromUserName>
          <CreateTime>%s</CreateTime>
          <MsgType><![CDATA[%s]]></MsgType>
          <Video>
            <MediaId><![CDATA[%s]]></MediaId>
            <Title><![CDATA[%s]]></Title>
          </Video>
        </xml>";
        $resultStr = sprintf($textTpl, $this->fromUsername, $this->toUsername, $this->time, 'video', $video,$keyword);
        throw new HttpResponseException(xml($resultStr));
    }
    private function newsreply($title,$desc,$img,$url)
    {
        $newsTpl="<xml>
        <ToUserName><![CDATA[%s]]></ToUserName>
        <FromUserName><![CDATA[%s]]></FromUserName>
        <CreateTime>%s</CreateTime>
        <MsgType><![CDATA[%s]]></MsgType>
        <ArticleCount>1</ArticleCount>
        <Articles>
        <item>
        <Title><![CDATA[%s]]></Title>
        <Description><![CDATA[%s]]></Description>
        <PicUrl><![CDATA[%s]]></PicUrl>
        <Url><![CDATA[%s]]></Url>
        </item>
        </Articles>
        </xml>";
        $resultStr = sprintf($newsTpl, $this->fromUsername, $this->toUsername, $this->time, 'news', $title,$desc,$img,$url);
        throw new HttpResponseException(xml($resultStr));
    }
    public function handleEventKey($key)
    {
        $obj=explode('_',$key);
        if(count($obj)>=2){
	        switch ($obj[0]) {
	            case 'jobs':
	                $this->getJobsInfo(intval($obj[1]));
	                break;
	            case 'company':
	                $this->getCompanyInfo(intval($obj[1]));
	                break;
	            case 'article':
	                $this->getArticleInfo(intval($obj[1]));
	                break;
                case 'bindadmin':
                    $this->bindadmin(intval($obj[1]));
                    break;
	        }
        }
    }
    public function getSelfOpenId()
    {
        $this->textreply($this->fromUsername);
    }
    public function bindadmin($id)
    {
        $AdminModel=AdminModel::where(['id'=>$id])->field('id,nickname,openid')->find();
        if($AdminModel){
            $AdminModel->openid=(String)$this->fromUsername;
            $ret=$AdminModel->save();
            $this->textreply('管理员'.$AdminModel->nickname.'绑定成功');
        }
        $this->textreply('管理员不存在');
    }
    public function getArticleInfo($article_id)
    {
        if($article_id){
            $Field=[
                'article.id,article.title,article.thumb,article.desc'
            ];

            $where=['article.id'=>$article_id];
            $ArticleModel=ArticleModel::alias('article')
                ->where($where)
                ->field(implode(",",$Field))
                ->withAttr('thumb',function($v,$data){
                    if($v){
                        $thumb=explode(',',$v);
                        return config('web.imgurl').$thumb[0];
                    }
                    return config('web.imgurl').config('web.icon');
                })
                ->find();
            if($ArticleModel){
                $title=$ArticleModel->title;
                $desc=$ArticleModel->desc;
                $url=config('web.url').'/article/content/'.$ArticleModel->id.'.html';
                $this->newsreply($title,$desc,$ArticleModel->thumb,$url);
            }
        }
        $this->sendWebsite();
    }
    public function getCompanyInfo($company_id)
    {
        if($company_id){
            $Field=[
                'c.id,c.title,c.stitle,c.logo',
                'industry.title as industry',
                'size_type.title as size_type',
                'city.title as city',
                'nature.title as nature',
                'finance.title as finance'
            ];

            $where=['c.id'=>$company_id];
            $CompanyModel=CompanyModel::alias('c')
                ->where($where)
                ->where(['size_type.alias'=>'company/size_type'])
                ->where(['nature.alias'=>'company/nature'])
                ->where(['finance.alias'=>'company/finance'])
                ->join('user user','user.id=c.uid')
                ->join('company_content content','content.cid=c.id')
                ->join('company_industry industry','industry.id=c.industry_id')
                ->join('status_alias size_type','size_type.value=c.size_type')
                ->join('status_alias nature','nature.value=c.nature')
                ->join('status_alias finance','finance.value=c.finance')
                ->join('area city','city.id = content.contacts_area1')
                ->field(implode(",",$Field))
                ->withAttr('logo',function($v,$data){
                    return $v?config('web.imgurl').$v:config('web.imgurl').config('xy_default_avatar.company_logo');
                })
                ->find();
            if($CompanyModel){
                $title=$CompanyModel->title;
                if($CompanyModel->stitle)
                    $title=$CompanyModel->stitle;
                $desc=$CompanyModel->city.' · '.$CompanyModel->size_type.' · '.$CompanyModel->nature.' · '.$CompanyModel->finance.' · '.$CompanyModel->industry;
                $url=config('web.url').'/company/'.$CompanyModel->id.'.html';
                $this->newsreply($title,$desc,$CompanyModel->logo,$url);
            }
        }
        $this->sendWebsite();
    }
    public function getJobsInfo($jobs_id)
    {
        if($jobs_id){
            $Field=[
                'jobs.id,jobs.title,jobs.salary_min,jobs.salary_max,jobs.salary_year',
                'company.title as company_name,company.stitle as company_sname,company.logo as company_logo',
                'city.title as jobs_city',
                'jobs_cate.title as jobs_cate_text',
                'education.title as education',
                'exp_level.title as exp_level'
            ];

            $where=['jobs.id'=>$jobs_id];
            $JobsModel=JobsModel::alias('jobs')
            ->where($where)
            ->whereNull('jobs.delete_time')
            ->where(['education.alias'=>'jobs/education_level'])
            ->where(['exp_level.alias'=>'jobs/exp_level'])
            ->join('company company','company.id=jobs.company_id')
            ->join('jobs_cate jobs_cate','jobs_cate.id=jobs.jobs_cate3')
            ->join('status_alias education','education.value=jobs.education_level')
            ->join('status_alias exp_level','exp_level.value=jobs.exp_level')
            ->join('area city','city.id = jobs.jobs_area2','LEFT')
            ->withAttr('company_logo',function($v,$data){
                return $v?config('web.imgurl').$v:config('web.imgurl').config('xy_default_avatar.company_logo');
            })
            ->field(implode(',',$Field))->find();
            if($JobsModel){
                $title=$JobsModel->title.'【'.$JobsModel->jobs_cate_text.'】';
                $salary='面议';
                if($JobsModel->salary_min>0)
                    $salary=$JobsModel->salary_min.'~'.$JobsModel->salary_max.'k';
                if($JobsModel->salary_year>12)
                    $salary.=$JobsModel->salary_year.'薪';
                $desc=$salary.' · '.$JobsModel->jobs_city.' · '.$JobsModel->exp_level.' · '.$JobsModel->education;
                $url=config('web.url').'/jobs/'.$JobsModel->id.'.html';
                $this->newsreply($title,$desc,$JobsModel->company_logo,$url);
            }
        }
        $this->sendWebsite();
    }
    public function sendWebsite()
    {
        $title=config('web.name');
        $desc=config('xy_seo.description');
        $img=config('web.imgurl').config('web.icon');
        $url='https://www.lzsf.com';
        $this->newsreply($title,$desc,$img,$url);
    }
    public function Bind()
    {
        $UserWxModel=UserWxModel::where(['wx_openid'=> $this->fromUsername])->find();
        if(!$UserWxModel){
            $wxInfo=WechatHelper::getUserInfo($this->fromUsername);
            $this->textreply(json_encode($wxInfo));
            if(!empty($wxInfo['unionid'])){
                $UserWxModel=UserWxModel::where(['unionid'=> $wxInfo['unionid']])->find();
            }
        }
        if($UserWxModel){
            $UserWxModel->wx_openid=$this->fromUsername;
            if($UserWxModel->save()){
                if($UserWxModel->uid)
                $this->textreply('您已绑定');
            }
        }
        $this->textreply('绑定账号：<a href="'.config('web.wechatmp').'/login" target="_blank">注册/登录</a>');
    }
    public function unBind()
    {
        $UserWxModel=UserWxModel::where(['wx_openid'=> $this->fromUsername])->find();
        if($UserWxModel){
            $UserWxModel->uid=null;
            if($UserWxModel->save()){
                Session::delete('WexinUser');
                $this->textreply('解绑成功');
            }else{
                $this->textreply('解绑失败');
            }
        }else{
            $this->textreply('该微信未绑定账号');
        }
    }
}